package it.megasoft78.turingmachine;

import java.util.ArrayList;
import java.util.HashMap;

public class TuringMachineEngine {
	private HashMap<String, TupleEntity> dTuples;
	private char[] tapeCells;
	private int currentPos;
	private String currentState;
	private TupleEntity lastTuple;
	public static final String START_STATE = "S";
	public static final String END_STATE = "E";

	public TuringMachineEngine(ArrayList<TupleEntity> tuples, char[] tapeCells) {
		dTuples = new HashMap<String, TupleEntity>(tuples.size());

		for (int t = 0; t < tuples.size(); t++) {
			TupleEntity tuple = tuples.get(t);

			dTuples.put(
					tuple.getCurrentState() + "|" + tuple.getScannedSymbol(),
					tuple);
		}

		this.tapeCells = tapeCells;
		this.currentPos = 0;
		this.currentState = TuringMachineEngine.START_STATE;
	}

	public TuringMachineAction nextStep() {
		TuringMachineAction action = null;

		String key = this.currentState + "|" + tapeCells[currentPos];
		lastTuple = dTuples.get(key);

		if (lastTuple != null) {
			this.currentState = lastTuple.getFinalState();

			tapeCells[currentPos] = lastTuple.getPrintSymbol().charAt(0);

			if (lastTuple.getMoveTape() == TupleEntity.LEFT) {
				if (currentPos > 0) {
					action = new TuringMachineAction(currentPos,
							currentPos - 1, lastTuple.getMoveTape(), lastTuple
									.getPrintSymbol().charAt(0),
							this.currentState == TuringMachineEngine.END_STATE);
					currentPos--;
				}
			} else if (lastTuple.getMoveTape() == TupleEntity.RIGHT) {
				if (currentPos < tapeCells.length) {
					action = new TuringMachineAction(currentPos,
							currentPos + 1, lastTuple.getMoveTape(), lastTuple
									.getPrintSymbol().charAt(0),
							this.currentState == TuringMachineEngine.END_STATE);
					currentPos++;
				}
			} else {
				action = new TuringMachineAction(currentPos, currentPos,
						lastTuple.getMoveTape(), lastTuple.getPrintSymbol()
								.charAt(0),
						this.currentState == TuringMachineEngine.END_STATE);
			}
		}

		return action;
	}

	public class TuringMachineAction {
		public int position;
		public int nextPosition;
		public int moveTape;
		public char printSymbol;
		public boolean end;

		public TuringMachineAction(int position, int nextPosition,
				int moveTape, char printSymbol, boolean end) {
			this.position = position;
			this.nextPosition = nextPosition;
			this.moveTape = moveTape;
			this.printSymbol = printSymbol;
			this.end = end;
		}
	}
}
